<?php

namespace App\Ma\Entities;

class CardItem extends Card
{


    /**
     * 将眼
     * @var integer
     */
    public $jiang;


    /**
     * 去除的顺子
     * @var array
     */
    public $shun = [];

    /**
     * 去除的克子
     * @var array
     */
    public $handKey = [];


    /**
     * 去除顺子后的矩阵
     * @var array
     */
    public $notThreeLinkCardMatrix;

    /**
     * 去除顺子、克子后的矩阵
     * @var array
     */
    public $notThreeCardMatrix;


    public function __construct(array $cards)
    {
        parent::__construct($cards);
        // 去除顺子
        $this->removeThreeLinkCards();
        // 去除克子
        $this->removeTheSameThreeCards();
    }


    /**
     * 检查胡牌
     * @param int $userCardType
     * @return bool
     */
    public function checkHu(int &$userCardType = 0): bool
    {
        if ($this->is13) {
            // 十三幺胡牌
            return true;
        }
        // 检测7对
        $laiZiCount = $this->getGuiCount();
        if (count($this->dui) === 7) { //七小对胡牌
            if (count($this->anGang) > 0) { // 七大对胡牌

            }
            return true;
        } elseif ($this->canUseLaiZiKangCount <= $laiZiCount) { //(癞子)七大对胡牌
            return true;
        } elseif ($this->canUseLaiZiCount <= $laiZiCount) { //(癞子)七小对胡牌
            return true;
        }
        // 存在癞子时
        $matrix = $this->notThreeCardMatrix;
        if ($laiZiCount > 0) {
            return $this->checkLaiZiHu($matrix, $laiZiCount);
        }

        // 不存在时
        return MatrixUtils::checkMatrixAllElemEqualZero($matrix); // 矩阵统计值是否全部为0
    }

    /**
     * 有鬼玩法检测是否胡牌
     * @param array $matrix
     * @param int $laiZiCount
     * @return bool
     */
    protected function checkLaiZiHu(array $matrix, int $laiZiCount): bool
    {
        foreach ($matrix as $type => $list) {
            foreach ($list as $key => $count) {
                if ($matrix[$type][$key] > 0) {
                    $temp = $matrix;
                    $needLaiZiCount = $temp[$type][$key] % 2;
                    $temp[$type][$key] = 0;
                    $needLaiZiCount = $this->checkNeedLaiZiCount($temp, $needLaiZiCount);
                    if ($needLaiZiCount <= $laiZiCount) {
                        return true;
                    }
                }
            }
            if (!$this->jiang) {
                $needLaiZiCount = $this->checkNeedLaiZiCount($matrix, 2);
                if ($needLaiZiCount <= $laiZiCount) {
                    return true;
                }
            }
            if ($type >= self::TYPE_SAN) {
                // 后续的鬼牌
                break;
            }
        }
        return false;
    }

    /**
     * 检测胡牌需要的癞子数
     * @param array $matrix
     * @param int $needLaiZiCount
     * @return int
     */
    protected function checkNeedLaiZiCount(array $matrix, int $needLaiZiCount): int
    {
        $minLaiZiCount = $needLaiZiCount;
        foreach ($matrix as $type => $list) {
            foreach ($matrix[$type] as $key => $count) {
                $count = $matrix[$type][$key]; //解决$matrix[$type][$value + 1]等造成的影响
                while ($count > 0) {
                    // 可构建顺子的花牌
                    if ($type < 3 && $key < 7) {
                        if ($matrix[$type][$key + 1] > 0) {
                            $matrix[$type][$key]--;
                            $matrix[$type][$key + 1]--;
                            $minLaiZiCount++;
                            $count--;
                            continue;
                        }
                        if ($matrix[$type][$key + 2] > 0) {
                            $matrix[$type][$key]--;
                            $matrix[$type][$key + 2]--;
                            $minLaiZiCount++;
                            $count--;
                            continue;
                        }

                    }
                    // 构建克子
                    if ($matrix[$type][$key] == 1) {
                        $matrix[$type][$key]--;
                        $minLaiZiCount += 2;
                        $count--;
                        continue;
                    }
                    if ($matrix[$type][$key] == 2) {
                        $matrix[$type][$key] -= 2;
                        $minLaiZiCount++;
                        $count -= 2;
                        continue;
                    }
                    $count--;
                }

            }
            if ($type >= self::TYPE_SAN) {
                // 后续的鬼牌
                break;
            }
        }
        return $minLaiZiCount;
    }

    /**
     * 去除顺子
     * @return void
     */
    protected function removeThreeLinkCards()
    {
        $matrix = $this->cardMatrix;
        foreach ($matrix as $type => $list) {
            foreach ($matrix[$type] as $key => $count) {
                $count = $matrix[$type][$key]; //解决$matrix[$type][$value + 1]等造成的影响
                if ($key >= 7) {
                    continue;
                }
                while ($count > 0) {
                    if ($matrix[$type][$key + 1] > 0 && $matrix[$type][$key + 2] > 0) {
                        $matrix[$type][$key]--;
                        $matrix[$type][$key + 1]--;
                        $matrix[$type][$key + 2]--;

                        array_push($this->shun, [
                            MatrixUtils::generateHexValue($type, $key + 1),
                            MatrixUtils::generateHexValue($type, $key + 2),
                            MatrixUtils::generateHexValue($type, $key + 3),
                        ]);
                    }
                    $count--;
                }

            }
            if ($type >= self::TYPE_TIAO) {
                // 后续的非花牌无顺子
                break;
            }
        }
        $this->notThreeLinkCardMatrix = $matrix;
    }

    /**
     * 移除刻子
     * @return void
     */
    protected function removeTheSameThreeCards()
    {
        $matrix = $this->notThreeLinkCardMatrix;
        if ($matrix) {
            foreach ($matrix as $type => $list) {
                foreach ($list as $key => $count) {
                    if ($count >= 3) {
                        $matrix[$type][$key] -= 3;
                        array_push($this->handKey, MatrixUtils::generateHexValue($type, $key + 1));
                    }
                }
                if ($type >= self::TYPE_SAN) {
                    // 后续的鬼牌
                    break;
                }
            }
            $this->notThreeCardMatrix = $matrix;
        }

    }

}